#region license
# This file is part of Grawlix.
# 
# Grawlix is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as
# published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
# 
# Grawlix is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public
# License along with Grawlix.  If not, see
# <http://www.gnu.org/licenses/>.
#endregion

"""Convert from string to a set of primitive types."""

namespace Grawlix.Services.Converters
import Grawlix.Services
import C5
import System
import System.Globalization
import System.Xml

transient class PrimitiveTypeConverter(ITypeConverter):
"""Convert to a primitive type from a string, using the invariant culture."""
	
	static def constructor():
	"""Initialization for this type."""
		_typeList = HashSet[of Type]()
		types = (bool, byte, char, date, DateTimeOffset, decimal, double, \
		Guid, short, int, long, sbyte, single, string, timespan, \
		ushort, uint, ulong, Uri)
		for type in types:
			_typeList.Add(type)
	
	def IsSupported([required] type as Type):
	"""
	Queries whether conversion to the specified type is
	possible with this converter.
	Param type: The type to try to convert to.
	Returns: true if possible, else false
	"""
		return _typeList.Contains(type)
	
	def Convert(
		[required] provder as ServiceProvider,
		[required] data as string,
		[required] type as Type):
	"""
	Converts the given data to the given type, if possible.
	Param provider: The service provider to recurse on, if needed.
	Param data: The string data to convert.
	Param type: The type to try to convert to.
	Returns: The converted object if successful.
	Raises ArgumentException: type is not supported.
	"""
		if type == bool:
			return XmlConvert.ToBoolean(data)
		elif type == byte:
			return XmlConvert.ToByte(data)
		elif type == char:
			return XmlConvert.ToChar(data)
		elif type == date:
			return XmlConvert.ToDateTime(data)
		elif type == DateTimeOffset:
			return XmlConvert.ToDateTimeOffset(data)
		elif type == decimal:
			return XmlConvert.ToDecimal(data)
		elif type == double:
			return XmlConvert.ToDouble(data)
		elif type == Guid:
			return XmlConvert.ToGuid(data)
		elif type == short:
			return XmlConvert.ToInt16(data)
		elif type == int:
			return XmlConvert.ToInt32(data)
		elif type == long:
			return XmlConvert.ToInt64(data)
		elif type == sbyte:
			return XmlConvert.ToSByte(data)
		elif type == single:
			return XmlConvert.ToSingle(data)
		elif type == string:
			return data
		elif type == timespan:
			return XmlConvert.ToTimeSpan(data)
		elif type == ushort:
			return XmlConvert.ToUInt16(data)
		elif type == uint:
			return XmlConvert.ToUInt32(data)
		elif type == ulong:
			return XmlConvert.ToUInt64(data)
		elif type == Uri:
			return Uri(data, UriKind.RelativeOrAbsolute)
		else:
			raise ArgumentException(
				"Specified type (${type}) is not supported.",
				"type")
	
	override def ToString():
	"""
	Get a string representation for this object.
	Returns: A string representation for this object.
	"""
		return "PrimitiveTypeConverter"
	
	private static _typeList as HashSet[of Type]
	"""A list of supported types."""
